import fetch from '@system.fetch';
import Md5 from '../utils/md5.js';
import * as HttpResponse from './httpResponse.js';
import * as Common from '../utils/common.js';
import EnvConfig from '../utils/envConfig.js';
import Base64 from '../utils/base64.js';

export function get2(url, resKey, serviceName, headers) {
    return fetchRequest(url, null, resKey, serviceName, headers)
}

export function post(url, data, resKey, serviceName, headers) {
    return fetchByMethod(url, data, resKey, serviceName, headers, "POST")
}

export function put(url, data, resKey, serviceName, headers) {
    return fetchByMethod(url, data, resKey, serviceName, headers, "PUT");
}

export function delete2(url, data, resKey, serviceName, headers) {
    return fetchByMethod(url, data, resKey, serviceName, headers, "DELETE");
}

export function postFormData(url, data, resKey, serviceName, headers) {
    return fetchRequest(url, {
        method: "POST",
        headers: {},
        data,
    }, resKey, serviceName, headers)
}

export function fetchByMethod(url, data, resKey, serviceName, headers, method) {
    return fetchRequest(url, {
        method: method || "POST",
        headers: { "Content-type": "application/json; charset=utf-8" },
        data
    }, resKey, serviceName, headers)
}

async function fetchRequest(url, data, resKey, serviceName, headers) {
        return new Promise(async (resolve) => {
            try {
                data = setParamsHeader(data, headers);
                data = await setServiceHeader(data, serviceName);
                url = getFullUrl(url);
                fetch.fetch({
                    url,
                    method: data.method,
                    header: data.headers,
                    responseType: 'json',
                    data: data.data,
                    success: function (res) {
                        resolve(HttpResponse.getResponse(res, resKey))
                    },
                    fail: function (err) {
                        const res = {
                            isSuccess: false,
                            message: err.message || err
                        };
                        resolve(HttpResponse.getErrorResponse(res));
                    }
                })
            }
            catch (error) {
                console.warn(error);
                const res={ isSuccess: false, message: error.message || error };
                resolve(HttpResponse.getErrorResponse(res));
            }
        });
}

function setParamsHeader(data, headers) {
    data = data || {};
    data.headers = data.headers || {};

    if (headers) {
        for (let key in headers) data.headers[key] = headers[key];
    }

    return data;
}

async function setServiceHeader(data, serviceName) {
    if (!serviceName) return data;

    if (serviceName === 'WebService') return data;

    const time = await getCurrentTime();

    data.headers.token = await Common.getStorage(EnvConfig.tokenKey);
    if (!data.headers.token || data.headers.isNoToken) data.headers.token = "d56b699830e77ba53855679cb1d252da" + Base64.encode(Common.createGuid());

    data.headers.access_token = getAccessToken(data.headers.token, time);

    return setApiServiceHeader(data, serviceName);
}

var _ClientConfig = {
};

function setApiServiceHeader(data, serviceName) {
    data = data || { headers: {}, method: "GET" };

    let clientId = "abet-account-app";

    if (_ClientConfig[serviceName]) clientId = _ClientConfig[serviceName];

    data.headers.clientTime = new Date().getTime();
    data.headers.clientId = clientId;
    data.headers.requestId = Common.createGuid().replace(/-/g, "").toLowerCase();

    return data;
}

var timeDiff=0;

function getCurrentTime() {
    const url = EnvConfig.apiService + "default/getCurrentTime";

    if (timeDiff) return Promise.resolve(new Date().getTime() + timeDiff);

    const startTime = new Date().getTime();
    return post(url, {}).then(res => {
        if (res.Time) {
            timeDiff = res.Time - startTime;
            return Promise.resolve(res.Time);
        }
        else return Promise.resolve(new Date().getTime());
    })
}

function getAccessToken(token, time) {
    const appId = 'D5ADDC90-5AB2-4B3D-8C38-5025E4068CFA';
    const md5str = Md5(appId + time + token);
    return Base64.encode(appId + '@' + time + "@" + md5str);
}

function getFullUrl(url) {
    return Common.addUrlRandom(url)
}